﻿// ------------------------------------------------------------------------
// 版权信息
// 版权归重庆虫儿飞科技有限公司所有。
// 所有权利保留。
// 官方网站：https://netokit.com
// 许可证信息
// Neto.Kit 项目主要遵循 MIT 许可证和 Apache 许可证（版本 2.0）进行分发和使用。
// 许可证的完整文本可以在源代码树根目录中的 LICENSE-APACHE 和 LICENSE-MIT 文件中找到。
// 
// 使用条款
// 使用本代码应遵守相关法律法规和许可证的要求。
// 
// 免责声明
// 对于因使用本代码而产生的任何直接、间接、偶然、特殊或后果性损害，我们不承担任何责任。
// 
// 其他重要信息
// Neto.Kit 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。
// 有关 Neto.Kit 项目的其他详细信息，请参阅位于源代码树根目录中的 COPYRIGHT 和 DISCLAIMER 文件。
// 
// 更多信息
// 请访问 https://netokit.com 获取更多关于 Neto.Kit 项目的许可证和版权信息。
// ------------------------------------------------------------------------

using Furion.DynamicApiController;
using Neto.Db.SqlSugar;
using Neto.Db.SqlSugar.Paged;
using Neto.Web;

namespace Neto.Application.Api;

/// <summary>
/// 用户锁定记录
/// </summary>
[Authorize]//jwt授权
[ApiDescriptionSettings("Api", Name = "SysUserLock")]
//[MaApi(controller: "SysUserLock", controllerDescription: "用户锁定记录", PCode = "Api")]
[ApiArea("Api")]
[PgApiController("用户锁定记录服务", MenuPCode = "Sys_Manage")]
[PgApiMenu("用户锁定记录", "manage_user-lock", MenuPCode = "Sys_Manage", Sort = 6)]
//[Route("Api/[controller]/[action]")]
public class ApiSysUserLockService(ISqlSugarClient db)
: IDynamicApiController
{
    /// <summary>
    /// 新增一条
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [PgApiAction(name: "新增一条")]
    [OperationId(nameof(Insert))]
    public async Task<long> Insert(ApiSysUserLockInput input)
    {
        ////验证 父级下 唯一 Key是否存在
        //var isexit = await db.Queryable<SysUserLock>().AnyAsync(o => o.PKey == input.PKey && o.Key == input.Key);
        //if (isexit)
        //{
        //    throw Oops.Bah("唯一标识Key不能重复");
        //}
        var addentity = input.Adapt<SysUserLock>();
        return await db.InsertRsIdAsync(addentity);
    }

    /// <summary>
    /// 更新一条
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [PgApiAction(name: "更新一条")]
    [OperationId(nameof(Update))]
    [HttpPut]
    public async Task<bool> Update(ApiSysUserLockInput input)
    {
        ////验证 父级下 唯一 Key是否存在
        //var isexit = await db.Queryable<SysUserLock>().AnyAsync(o => o.PKey == input.PKey && o.Key == input.Key && o.Id != input.Id);
        //if (isexit)
        //{
        //    throw Oops.Bah("唯一标识Key不能重复");
        //}
        var dbentity = await db.Queryable<SysUserLock>().With(SqlWith.Null).FirstAsync(o => o.Id == input.Id.Value);
        input.Adapt(dbentity);
        return await db.UpdateAsync(dbentity);

    }

    /// <summary>
    /// 删除一条
    /// </summary>
    /// <param name="id"></param>
    [PgApiAction(name: "删除一条")]
    [OperationId(nameof(Delete))]
    public async Task<bool> Delete(long id)
    {
        //if (id <= 0) throw Oops.Bah("id不能为0");
        //return  await db.DeleteByIdAsync<SysUserLock>(id);
        return await db.FakeDeleteAsync<SysUserLock>($"{id}");
    }

    /// <summary>
    /// 批量删除
    /// </summary>
    /// <param name="ids">需要删除的数据，多条以英文逗号隔开</param>
    [PgApiAction(name: "批量删除")]
    [OperationId(nameof(BatchDelete))]
    public async Task<bool> BatchDelete(string ids)
    {
        //return await db.DeleteByIdsAsync<SysUserLock>(ids);
        return await db.FakeDeleteAsync<SysUserLock>(ids);
    }

    /// <summary>
    /// 查询一条
    /// </summary>
    /// <param name="id"></param>
    [PgApiAction(name: "查询一条")]
    [HttpPost]
    [OperationId(nameof(Get))]
    public async Task<ApiSysUserLockOut> Get(long id)
    {
        /* 多表关联的一个写法，当然也可以用导航写法
         var query5 = await db.Queryable<SysUserLock>()
           //.LeftJoin<Custom>   ((o, cus ) => o.CustomId == cus.Id)//多个条件用&&
           //.LeftJoin<OrderDetail> ((o, cus, oritem) => o.Id == oritem.OrderId)
           .Where(o => o.Id == id)  
           .Select((o) => new ApiSysUserLockOut {
                Id = o.Id.SelectAll(), //Id是o任意一个属性
                //CustomName = cus.Name,
            })
           .FirstAsync();
        */

        return await db.GetByIdAsync<SysUserLock, ApiSysUserLockOut>(id);
    }


    /// <summary>
    /// 分页查询
    /// </summary>
    /// <param name="searchQuery"></param>
    /// <returns></returns>
    [PgApiAction(name: "分页查询")]
    [HttpPost]
    [OperationId(nameof(GetList))]
    public async Task<PagedList<ApiSysUserLockOut>> GetList(ApiSysUserLockQuery searchQuery)
    {
        /*
            var queryable = db.Queryable<SysUserLock, OrderItem, Custom>((o, i, c) => new JoinQueryInfos(
                   JoinType.Left, o.Id == i.OrderId, //左连接 左链接 左联 
                   JoinType.Left, o.CustomId == c.Id 
            ));
        */

        var queryable = db.Queryable<SysUserLock>()
            .Includes(o => o.ManualUnlockUser)
            .Includes(o => o.LockUser)
            ;
        #region 筛选条件
        if (searchQuery.IsManualUnlock.HasValue)
        {
            queryable = queryable.Where(o => o.IsManualUnlock == searchQuery.IsManualUnlock.Value);

        }

        if (searchQuery.LoginRuleType.HasValue)
        {
            queryable = queryable.Where(o => o.LoginRuleType == searchQuery.LoginRuleType.Value);

        }
        //开始日期
        if (searchQuery.StartDate.HasValue)
        {
            queryable = queryable.Where(o => o.CreationTime >= searchQuery.StartDate.Value);
        }
        //结束日期
        if (searchQuery.EndDate.HasValue)
        {
            queryable = queryable.Where(o => o.CreationTime <= searchQuery.EndDate.ToDayEndTime());
        }
        //关键词
        if (!string.IsNullOrWhiteSpace(searchQuery.KeyWords))
        {

            var kw = searchQuery.KeyWords?.Trim()?.ToLower() ?? "";
            if (kw.IsValidLong())
            {
                var tempId = kw.ToLong();

                queryable = queryable.Where(o =>
                    o.Id == tempId || o.LockUserId == tempId ||
                    o.ManualUnlockUserId == tempId || o.RuleId == tempId ||
                    o.Ip.Contains(kw) || o.Reason.Contains(kw) ||
                    o.ManualUnlockUser.Account.Contains(kw) || o.ManualUnlockUser.Nick.Contains(kw) ||
                    o.LockUser.Account.Contains(kw) || o.LockUser.Nick.Contains(kw)
                 );
            }
            else
            {
                queryable = queryable.Where(o => o.Ip.Contains(kw) || o.Reason.Contains(kw)
                || o.ManualUnlockUser.Account.Contains(kw) || o.ManualUnlockUser.Nick.Contains(kw)
                || o.LockUser.Account.Contains(kw) || o.LockUser.Nick.Contains(kw)
                );
            }
        }
        #endregion

        queryable = queryable.OrderByDescending(o => o.Id);
        var pagelist = await queryable.Select(o => new ApiSysUserLockOut()
        {
            Id = o.Id.SelectAll(),
            #region 自定义
            LockUserName = o.LockUser.Account,
            ManualUnlockUserName = o.ManualUnlockUser.Account,

            //IsManualUnlockName =  o.IsManualUnlock?"是":"否"  ,//是否手动解锁 
            //IsDeletedName =  o.IsDeleted?"是":"否"  ,//默认假删除 
            #endregion
        })
        .Mapper(src =>
        {
        })
        .ToPagedListAsync(searchQuery.PageIndex, searchQuery.PageSize);



        //var pagelist= await pageResult.ToPagedListAsync<SysUserLock, ApiSysUserLockOut>(searchQuery.PageIndex, searchQuery.PageSize);

        return pagelist;
    }


    /// <summary>
    /// 手动解锁
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [PgApiAction(name: "设置启用状态")]
    [OperationId(nameof(ManualUnlock))]
    public async Task<bool> ManualUnlock(long id)
    {
        try
        {

            var loginUserId = App.HttpContext.GetLoginUserId();
            var dbmodel = await db.Queryable<SysUserLock>()
                .Where(it => it.Id == id)
                .FirstAsync();
            if (dbmodel != null)
            {

                await db.Ado.BeginTranAsync();

                dbmodel.IsManualUnlock = true;
                dbmodel.ManualUnlockTime = DateTime.Now;
                dbmodel.ManualUnlockUserId = loginUserId;
                await db.UpdateAsync(dbmodel);


                //将这个规则下的所选ip解禁
                if (dbmodel.LoginRuleType==LoginRuleType.Ip&&dbmodel.SysLoginAttemptIPId.HasValue)
                {
                    var ipLoginAttemptList = db.Queryable<SysLoginAttemptIP>();

                    await db.Updateable<SysLoginAttemptIP>()
                        .SetColumns(it => it.IsManualUnlock == true)
                        .Where(it => it.GroupId == dbmodel.SysLoginAttemptIPId.Value)
                        .ExecuteCommandAsync();
                }



                await db.Ado.CommitTranAsync();
            }

            return true;
        }
        catch (Exception)
        {
            await db.Ado.RollbackTranAsync();
            return false;
        }
    }

    #region 冗余方法
    ///// <summary>
    ///// 查询所有
    ///// </summary>
    ///// <returns></returns>
    //[PgApiAction(name: "查询所有")]
    //[OperationId(nameof(GetAll))]
    //public async Task<List<ApiSysUserLockOut>> GetAll()
    //{
    //    return await db.GetListAsync<SysUserLock, ApiSysUserLockOut>();
    //}

    ///// <summary>
    ///// 获取下拉选项
    ///// </summary>
    ///// <returns></returns>
    //[PgApiAction(name: "获取下拉选项")]
    //[HttpPost]
    //[OperationId(nameof(GetSelectItems))]
    //public async Task<List<NKeyValue<long, string>>> GetSelectItems()
    //{
    //    var keyValues = await db.Queryable<SysUserLock>()
    //        .Select(o => new NKeyValue<long, string>() { Key = o.Id, Value = o.Name })
    //        .ToListAsync();
    //    return keyValues;
    //}


    #endregion

}